package cn.com.shopec.erp.purchase.service.imp;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.UUID;

import javax.annotation.Resource;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.hibernate.Hibernate;
import org.hibernate.Query;
import org.hibernate.criterion.DetachedCriteria;
import org.hibernate.criterion.MatchMode;
import org.hibernate.criterion.Order;
import org.hibernate.criterion.Restrictions;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.ui.ModelMap;

import cn.com.shopec.erp.base.service.IAuditSettingService;
import cn.com.shopec.erp.common.constant.ProductSCMConstant;
import cn.com.shopec.erp.common.constant.SZSCMConstant;
import cn.com.shopec.erp.common.excep.WMSException;
import cn.com.shopec.erp.common.page.PageFinder;
import cn.com.shopec.erp.common.page.PageQuery;
import cn.com.shopec.erp.common.utils.DateUtil;
import cn.com.shopec.erp.common.utils.LogicUtil;
import cn.com.shopec.erp.common.utils.StringUtil;
import cn.com.shopec.erp.common.utils.UuidGenUtils;
import cn.com.shopec.erp.financing.entity.PurchaserOrder;
import cn.com.shopec.erp.product.commo.DefectiveVoConvertor;
import cn.com.shopec.erp.product.entity.Defective;
import cn.com.shopec.erp.product.entity.Product;
import cn.com.shopec.erp.product.entity.ProductInventory;
import cn.com.shopec.erp.product.service.ICommodityService;
import cn.com.shopec.erp.product.vo.DefectiveVo;
import cn.com.shopec.erp.product.vo.ProductVo1;
import cn.com.shopec.erp.provideinterface.entity.InventoryChange;
import cn.com.shopec.erp.purchase.commo.POPropertyUtils;
import cn.com.shopec.erp.purchase.commo.PRPropertyUtils;
import cn.com.shopec.erp.purchase.commo.PurchaseRequisitionProductVoConvertor;
import cn.com.shopec.erp.purchase.commo.PurchaseVoConvertor;
import cn.com.shopec.erp.purchase.constant.ReturnedPOConstant;
import cn.com.shopec.erp.purchase.dao.IPoProductDao;
import cn.com.shopec.erp.purchase.dao.IPurchaseOrderDao;
import cn.com.shopec.erp.purchase.dao.IPurchaseRequisitionProductDao;
import cn.com.shopec.erp.purchase.entity.PoProduct;
import cn.com.shopec.erp.purchase.entity.PurchaseOrder;
import cn.com.shopec.erp.purchase.entity.PurchaseRequisitionProduct;
import cn.com.shopec.erp.purchase.entity.PurchaseReturnOrder;
import cn.com.shopec.erp.purchase.model.PoAuditPoint;
import cn.com.shopec.erp.purchase.model.PoProductInfo;
import cn.com.shopec.erp.purchase.model.PurchaseOrderDetail;
import cn.com.shopec.erp.purchase.model.PurchaseOrderInfo;
import cn.com.shopec.erp.purchase.model.PurchaseOrderQuery;
import cn.com.shopec.erp.purchase.service.IPurchaseOrderService;
import cn.com.shopec.erp.purchase.vo.PurchaseOrderVo;
import cn.com.shopec.erp.purchase.vo.PurchaseRequisitionProductVo;
import cn.com.shopec.erp.system.common.UserUtils;
import cn.com.shopec.erp.system.constant.SystemConstant;

/** 
 * @ClassName: PurchaseOrderServiceImpl 
 * @Description: 采购单业务service实现
 * @author: lule
 * @date 2013-5-22 上午11:06:35
 *  
 */
@Service
public class PurchaseOrderServiceImpl implements IPurchaseOrderService {
	
	private static Log log = LogFactory.getLog(PurchaseOrderServiceImpl.class);
	
	@Resource
	private IPurchaseOrderDao poDao;
	
	@Resource 
	private IAuditSettingService auditSettingService;
	
	@Resource
	private ICommodityService commodityService;
	
	@Resource
	private PurchaseVoConvertor purchaseVoConvertor;
	
	@Resource 
	private IPurchaseRequisitionProductDao prpdao;
	
	@Resource
	private IPoProductDao poProdDao;
	
	@Resource
	private IPurchaseRequisitionProductDao requestDao;
	
	@Resource
	private PurchaseRequisitionProductVoConvertor requestconvertor;
	
	@Override
	@Transactional
	public PageFinder<PurchaseOrderInfo> getPagedPurchaseOrders(PurchaseOrderQuery query, PageQuery pageQuery) {
		
		return null;
	}

	@Override
	@Transactional
	public PageFinder<PurchaseOrderVo> getPagedPurchaseOrderList(PurchaseOrderVo query, PageQuery pageQuery) throws Exception {
		DetachedCriteria criteria = this.poDao.createCriteria();

	        if(query!=null){

				//根据采购单号查
				if(!StringUtil.isBlank(query.getPoNo())){
					criteria.add(Restrictions.ilike("poNo", query.getPoNo().trim(),MatchMode.ANYWHERE));
				} 
				
				//根据采购单名称
				if(!StringUtil.isBlank(query.getPoName())){
					criteria.add(Restrictions.ilike("poName", query.getPoName().trim(),MatchMode.ANYWHERE));
				} 
				
				//是否需要加入当前审核节点作为条件
				/*if(query.getCurAuditPoint() != null){
					criteria.add(Restrictions.eq("curAuditPoint", query.getCurAuditPoint()));
				}*/
				
				//采购单状态做查询条件
				if(query.getPoStatus()!=null){
					criteria.add(Restrictions.eq("poStatus", query.getPoStatus()));
				}
				//创建人
				if(!StringUtil.isBlank(query.getCreatePerson())){
					criteria.add(Restrictions.eq("createPerson", query.getCreatePerson().trim()).ignoreCase());
				}
				
				//供应商名称
				if(!StringUtil.isBlank(query.getSupName())){
					criteria.add(Restrictions.like("supName", query.getSupName().trim(),MatchMode.ANYWHERE));
				}
				
				/*if(query.getPpNumber()!=0){
					criteria.add(Restrictions.eq("createPerson", query.getCreatePerson().trim()).ignoreCase());
				}*/
				
			}
				
	        criteria.add(Restrictions.eq("deleteFlag", SZSCMConstant.DELETE_FLAG_NO)); //未删除
			criteria.addOrder(Order.desc("createTime")); //默认按采购单创建的时间排序
		  PageFinder<PurchaseOrder> pagedBrandList = this.poDao.pagedByCriteria(criteria, pageQuery.getPage(),pageQuery.getPageSize());

	        return this.purchaseVoConvertor.convert2PagedDefectiveVos(pagedBrandList);
	    }

	/**
     * 
     * @Title: getBrand
     * @Description: 根据编号查询次品信息
     * @param productId
     * @throws Exception
     * @throws
     * @author: LiangShunWang
     * @date: 2013-5-26下午05:02:06
     */
	@Override
	public PurchaseOrderVo getPurchaseOrder(String poNo) {
		 return this.purchaseVoConvertor.convert2DefectiveVo(this.poDao.get("poNo", poNo));
	}

	

	/**
     * 
     * @Title: addPurchase
     * @Description: 增加采购信息
     * @param brandVo
     * @return
	 * @throws Exception 
     * @throws
     * @author: Liangshunwang
     * @date: 2013-5-26下午04:17:40
     */
	@Override
	public void addPurchase(PurchaseOrderVo purchase) throws Exception {
		PurchaseOrder purchaseOrder = this.purchaseVoConvertor.convert2Defective(purchase);
		purchaseOrder.setCreateTime(DateUtil.formatTimesTampDate(new Date()));
		poDao.save(purchaseOrder);
	}

	/**
     * 
     * @Title: delete
     * @Description: 删除采购信息
     * @param brandVo
     * @return
	 * @throws Exception 
     * @throws
     * @author: Liangshunwang
     * @date: 2013-5-26下午04:17:40
     */
	@Override
	@Transactional
	public void deletePurchase(String id) throws Exception {
        if (LogicUtil.isNotNullAndEmpty(id)) {
            PurchaseOrder purchaseOrder = this.poDao.get("id", id);
            if (LogicUtil.isNotNull(purchaseOrder)) {
            	purchaseOrder.setDeleteFlag(SZSCMConstant.DELETE_FLAG_YES);
            	 this.poDao.update(purchaseOrder);
            }
        }
		
	}
	

	/**
	 * @methodName：addPurchaseRequisitionVo
	 * @Description: 添加请购单
	 * @param PurchaseRequisitionVo
	 * @return ModelMap
	 * @author: gaoyaxiong
	 * @date: 2013-5-21 下午18:22:03
	 */
	@Override
	@Transactional
	public String addPurchaseRequisitionVo(PurchaseOrderVo prv) {
		ModelMap modelMap = new ModelMap();
		PurchaseOrder pr = PRPropertyUtils.getNewRequisition(prv);
		if(!purchaseOrderBypuNo(pr.getPoNo())){
			return SZSCMConstant.FAILREPEAT;
		}
		
		List<PurchaseRequisitionProductVo> prplist =  prv.getPrpvlist();
		List<PurchaseRequisitionProductVo> prplistEx = new ArrayList<PurchaseRequisitionProductVo>();
		
		try {
			PurchaseOrder spr = poDao.save(pr);
			
			for (PurchaseRequisitionProductVo prpv : prplist) {
				/** 验证商品是否存在 **/
				ProductVo1 productVo = commodityService.getProduct(prpv.getProductNo());
				if(productVo != null){
					PurchaseRequisitionProduct prp = new PurchaseRequisitionProduct();
					prp = PRPropertyUtils.getNewPrP(prpv,productVo);
					prp.setPoNo(spr.getPoNo());
					prp.setPpSupplierNo(prv.getSupCode());
					prp.setPpSupplierName(prv.getSupName());
					prp.setRetunStatus(0);
					//数量
					/*prp.setPpNumber(prv.getPpNumber());
					//价格
					prp.setPpUnitPrice(prv.getPpUnitPrice());
					//总价
					prp.setTotalPrice(prv.getTotalPrice());*/
					prpdao.save(prp);
				}else{
					prplistEx.add(prpv);
				}
			}
			modelMap.put("prplistEx", prplistEx);
		} catch (Exception e) {
			e.printStackTrace();
			e.getMessage();
			return SZSCMConstant.FAIL;
		}
		
		return SZSCMConstant.SUCCESS;
	}
	
	/**
     * 
     * @Title: updateBrand
     * @Description: 修改次品信息
     * @param brandVo
     * @return
     * @throws
     * @author: duhui
     * @date: 2013-5-26下午04:17:40
     */
	@Override
	public void updatePurchaseOrder(PurchaseOrderVo purchaseOrderVo) throws Exception {
		if (LogicUtil.isNotNull(purchaseOrderVo)) {
        	PurchaseOrder purchase = this.poDao.get("poNo",purchaseOrderVo.getPoNo());
//        	this.poDao.update(this.purchaseVoConvertor.convert2Defective(purchaseOrderVo, purchase));
        }
	}

	@Override
	public boolean isModifiablePo(PurchaseOrderInfo po) {
		if(po != null) {
			//PO状态为"申请中"，并且PO的当前审核节点为"采购主管"(说明尚被审核过)或"结束"(说明已经被采购主管拒绝)
			if(po.getPoStatus() == SZSCMConstant.PO_STATUS_APPLYING 
					&& (PoAuditPoint.PO_AUDIT_POINT_PURCH_SU.getCode() == po.getCurAuditPoint() 
							|| PoAuditPoint.PO_AUDIT_POINT_FINISH.getCode() == po.getCurAuditPoint()))
				return true;
			else
				return false;
		} else {
			return false;
		}
	}

	@Override
	public PurchaseOrderDetail getPurchaseOrderDetail(String poNo) throws Exception {
		PurchaseOrderDetail detail = null;
		PurchaseOrder po = poDao.get("poNo", poNo);
		
		if(po != null) {
			detail = POPropertyUtils.getPurchaseOrderDetail(po);
		}
		
		return detail;
	}
	
	@Override
	@Transactional
	public PageFinder<PoProductInfo> getPagedPoProducts(String poNo, PageQuery pageQuery) throws Exception {
		DetachedCriteria criteria = poProdDao.createCriteria();
		criteria.add(Restrictions.eq("poNo", poNo.trim()).ignoreCase());
		criteria.addOrder(Order.asc("prodNo")); //默认按货品号顺排
		
		PageFinder<PoProduct> page = poProdDao.pagedByCriteria(criteria, pageQuery != null ? pageQuery.getPage() : 1, pageQuery != null ? pageQuery.getPageSize() : Integer.MAX_VALUE);
		
		PageFinder<PoProductInfo> retPage = new PageFinder<PoProductInfo>(page.getPageNo(), page.getPageSize(), page.getRowCount(), 
																			POPropertyUtils.getPoProductInfoList(page.getData()));
		
		return retPage;
	}

	/** 
	 * @Title: updatePurchaseOrderByAudit 
	 * @Description: 采购主管审核
	 * @param poNo
	 * @param pageQuery
	 * @return
	 * @throws Exception  
	 * @throws 
	 * @author: Liang shun wang
	 * @date: 2013-5-27上午10:09:46
	 */
	@Override
	@Transactional
	public void updatePurchaseOrderByAudit(PurchaseOrderVo purchaseOrderVo) throws Exception {
		
		if (LogicUtil.isNotNull(purchaseOrderVo)) {/*
			double poAmount = this.getPurchaseOrderPriceAmount(purchaseOrderVo.getPoNo()); //算出po金额
				if (!auditSettingService.checkNeedsAudit(purchaseOrderVo.getCurAuditPoint(), String.valueOf(poAmount))) {
					res = -3; // 审核金额未达到需要审核的金额
					return res;
				}else{
					PurchaseOrder purchase = this.poDao.get("poNo",purchaseOrderVo.getPoNo());
					purchase.setCurAuditPoint(ReturnedPOConstant.CURRENT_AUDIT_POINT_99);
					purchase.setPoStatus(-2);
		        	this.poDao.update(this.purchaseVoConvertor.convert2Defective(purchaseOrderVo, purchase));
				}
        */
			PurchaseOrder purchase = this.poDao.get("poNo",purchaseOrderVo.getPoNo());
			//预计采购时间
			purchase.setFoPurDate(DateUtil.formatTimesTampDate(DateUtil.getCurrentDate()));
			//上次审核人身份
			purchase.setLastAuditRole(UserUtils.getLoginUserRealName());
			//最新审核时间
			purchase.setLastAuditTime(DateUtil.formatTimesTampDate(DateUtil.getCurrentDate()));
			//审核结果
			purchase.setAuditResult(purchaseOrderVo.getAuditResult());
			//采购流程
			purchase.setPoStatus(purchaseOrderVo.getAuditResult());
			//描述
			purchase.setRemark(purchaseOrderVo.getRemark());
			//采购单状态
//			purchase.setPoStatus(ProductSCMConstant.LASTAUDITRESULT_OK);
			
			/*purchase.setCurAuditPoint(ReturnedPOConstant.CURRENT_AUDIT_POINT_99);
			purchase.setPoStatus(-2);
			purchase.setAuditResult(purchaseOrderVo.getAuditResult());
			purchase.setRemark(purchaseOrderVo.getRemark());
			purchase.setAuditTime(DateUtil.formatTimesTampDate(DateUtil.getCurrentDate()));
			purchase.setLastAuditTime(DateUtil.formatTimesTampDate(DateUtil.getCurrentDate()));*/
        	this.poDao.update(this.purchaseVoConvertor.convert2Defective(purchaseOrderVo, purchase));
			}
	}
	
	
	/** 
	 * @Title: getPurchaseOrderPriceAmount 
	 * @Description: 判断审核金额是否达到要求
	 * @param poNo
	 * @param pageQuery
	 * @return
	 * @throws Exception  
	 * @throws 
	 * @author: Liang shun wang
	 * @date: 2013-5-27上午10:09:46
	 */
	@Override
	public double getPurchaseOrderPriceAmount(String poNo) throws Exception {
		double amount = 0.0d;
		Object obj = poProdDao.getObjectByHql("select sum(p.purUnitPrice * p.purQuantity) as priceAmount from PoProduct p where p.poNo=?",poNo);
		
		amount = obj == null ? amount : Double.parseDouble(obj.toString());
		return amount;
	}
	
	/** 
	 * @Title: getPoProduct 
	 * @Description: 根据采购单号和货品号，取得一个采购单货品信息
	 * @param poNo
	 * @param prodNo
	 * @return
	 * @throws Exception  
	 * @throws 
	 * @author: Liang Shun wang
	 * @date: 2013-5-27下午5:35:17
	 */
	@Override
	public PoProductInfo getPoProduct(String poNo, String prodNo) throws Exception {
		PoProduct o = poProdDao.getObjectByHql("from PoProduct p where p.poNo=? and p.prodNo=?", poNo, prodNo);
		
		return POPropertyUtils.getPoProductInfo(o);
	}
	
	/** 
	 * @Title: updatePoProductPriceAndQuantity 
	 * @Description: 更新采购单中某个货品的采购单价和采购数量
	 * @param poNo
	 * @param prodNo
	 * @param unitPrice
	 * @param quantity
	 * @return 操作结果代码。(1:成功、0:失败、 -1:失败，参数采购单编号不正确、 -2:失败，当前采购单不能作废、-3:失败，参数采购单号或货品号不正确)
	 * @throws Exception  
	 * @throws 
	 * @author: LiangShunWang
	 * @date: 2013-5-24下午9:35:26
	 */
	@Override
	@Transactional
	public int updatePoProductPriceAndQuantity(String poNo, String prodNo, double unitPrice, int quantity) throws Exception {
		int res = SZSCMConstant.FAIL_INT;
		try {
			PurchaseOrder po = poDao.get("poNo", poNo); //先取出采购单，并基于采购单做判断
			if(po == null) {
				res = -1;
			} else if(!isModifiablePo(po)) { //判断当前是否可以对PO进行修改
				res = -2;
			} else {
				PoProduct poProd = poProdDao.getObjectByHql("select p from PoProduct p where p.deleteFlag=1 and p.poNo=? and p.prodNo=?", poNo, prodNo);
				if(poProd == null) {
					res = -3;
				} else { //更新单价及数量
					poProd.setPurUnitPrice(unitPrice);
					poProd.setPurQuantity(quantity);
					
					poProdDao.update(poProd);
					PurchaseOrder purchaseOrder = poDao.findUniqueBy("poNo", poProd.getPoNo());
					purchaseOrder.setCurAuditPoint(SZSCMConstant.PO_AUDIT_POINT_PURCH_SU);
					poDao.update(purchaseOrder);
					
					res = SZSCMConstant.SUCCESS_INT;
				}
			}
			
		} catch (Exception e) {
			log.error(e.getMessage(), e);
			throw e;
		}
		
		return res;
	}
	
	/**
	 * 判断是否是可以修改的PO单（包括可以修改订货数量、价格已经可以将PO作废） 
	 * @param po
	 * @return  
	 * @throws 
	 * @author: lule
	 */
	private boolean isModifiablePo(PurchaseOrder po) {
		//PO状态为"申请中"，并且PO的当前审核节点为"采购主管"(说明尚被审核过)或"结束"(说明已经被采购主管拒绝)
		/*if(po.getPoStatus() == SZSCMConstant.PO_STATUS_APPLYING 
				&& (PoAuditPoint.PO_AUDIT_POINT_PURCH_SU.getCode() == po.getCurAuditPoint() 
						|| PoAuditPoint.PO_AUDIT_POINT_FINISH.getCode() == po.getCurAuditPoint())){
			return true;
		}
		else{
			return false;
		}*/
		return true;
	}

	@Override
	@Transactional
	public PageFinder<PurchaseRequisitionProductVo> getPagedPoProducts2(String poNo, PageQuery pageQuery)
			throws Exception {
		DetachedCriteria criteria = this.requestDao.createCriteria();
		if(poNo!=null){

			//已采购单号做查询条件
			if(!StringUtil.isBlank(poNo)){
				criteria.add(Restrictions.ilike("poNo", poNo.trim(),MatchMode.ANYWHERE));
			} 
		}
		  PageFinder<PurchaseRequisitionProduct> pagedBrandList = this.requestDao.pagedByCriteria(criteria, pageQuery.getPage(),pageQuery.getPageSize());

	        return this.requestconvertor.convert2PagedDefectiveVos(pagedBrandList);
	}

	/** 
	 * @Title: updatePoProductPriceAndQuantity 
	 * @Description:根据采购单号查询采购单名称
	 * @param poNo
	 * @throws Exception  
	 * @throws 
	 * @author: Liang Shun Wang
	 * @date: 2013-5-24下午9:35:26
	 */
	@Override
	public PageFinder<PurchaseOrderVo> getPurchaseOrderById(String poNo,PageQuery pageQuery) throws Exception {
		DetachedCriteria criteria = this.poDao.createCriteria();

        if(poNo!=null){
			//已采购单号做查询条件
		    criteria.add(Restrictions.ilike("poNo", poNo.trim(),MatchMode.ANYWHERE));
        }
        criteria.add(Restrictions.eq("deleteFlag", SZSCMConstant.DELETE_FLAG_NO)); //未删除
	    PageFinder<PurchaseOrder> pagedBrandList = this.poDao.pagedByCriteria(criteria, pageQuery.getPage(),pageQuery.getPageSize());
        return this.purchaseVoConvertor.convert2PagedDefectiveVos(pagedBrandList);
    }

	/**
     * 
     * @Title: updateAuditResultPurchaseOrder
     * @Description: 修改采购单状态信息
     * @param brandVo
     * @return
     * @throws
     * @author: Liang Shun Wang
     * @date: 2013-5-26下午04:17:40
     */
	@Override
	public void updateAuditResultPurchaseOrder(String purchaseNo,int status) throws Exception {
		if (LogicUtil.isNotNull(purchaseNo)) {
        	PurchaseOrder purchase = this.poDao.get("poNo",purchaseNo);
        	
        	this.poDao.update(this.purchaseVoConvertor.convert2DefectiveUpdateAuditResult(purchaseNo, purchase,status));
        }
	}
	
	
	/** 
	 * @Title: updatePurchaseOrderByAudit 
	 * @Description: 采购
	 * @param poNo
	 * @param pageQuery
	 * @return
	 * @throws Exception  
	 * @throws 
	 * @author: Liang shun wang
	 * @date: 2013-5-27上午10:09:46
	 */
	@Override
	@Transactional
	public void purchaseOrderList(String poNo) throws Exception {
		
		if (LogicUtil.isNotNull(poNo)) {
			
			PurchaseOrder purchase = this.poDao.get("id",poNo);
			//修改时间
			purchase.setPrCreaterDate(DateUtil.formatTimesTampDate(DateUtil.getCurrentDate()));
			
        	this.poDao.update(this.purchaseVoConvertor.convert2DefectiveList(poNo, purchase));
			}
	}

	@Override
	public boolean updatePurchaseOrderTotalPrice(String purchaseNo,Double price) throws Exception {
		boolean bool = false;
		if (LogicUtil.isNotNull(purchaseNo)) {
			PurchaseOrder purchase = this.poDao.get("poNo",purchaseNo);
			purchase.setTotalPrice(price);
			this.poDao.update(purchase);
			bool = true;
		}
		return bool;
		
	}

	@Override
	public boolean purchaseOrderBypuNo(String poNo) {
		boolean bool = false;
		if(!poNo.equals("") && poNo!=null){
			DetachedCriteria criteria = this.poDao.createCriteria();
			 criteria.add(Restrictions.eq("poNo", poNo));
			    criteria.add(Restrictions.eq("deleteFlag", SZSCMConstant.DELETE_FLAG_NO));
			    List<PurchaseOrder> productList = this.poDao.findByCriteria(criteria);
			    if (LogicUtil.isNotNullAndEmpty(productList)) {
			    	return bool;
			    }else{
			    	bool = true;
			    }
		}else{
			return bool;
		}
		return bool;
	}
	
}